<template>
  <div class="p-2">
    <el-form ref="augmentationFormRef" :model="form" :rules="rules" label-width="120px">
      <el-form-item label="批量大小" prop="batchSize">
        <el-input v-model="form.batchSize" placeholder="请输入批量大小" />
      </el-form-item>
      <el-form-item label="迭代次数" prop="iterationNum">
        <el-input v-model="form.iterationNum" placeholder="请输入迭代次数" />
      </el-form-item>
      <el-form-item label="生成器学习率" prop="generatorRate">
        <el-input v-model="form.generatorRate" placeholder="请输入生成器学习率" />
      </el-form-item>
      <el-form-item label="判别器学习率" prop="discriminatorRate">
        <el-input v-model="form.discriminatorRate" placeholder="请输入判别器学习率" />
      </el-form-item>
      <el-form-item label="生成样本个数" prop="sampleNum">
        <el-input v-model="form.sampleNum" placeholder="请输入生成样本个数" />
      </el-form-item>
    </el-form>
    <div class="dialog-footer">
      <el-button :loading="buttonLoading" type="primary" @click="submitForm">开始数据增强</el-button>
      <el-button plain type="success" @click="reset">重 置</el-button>
      <el-button @click="cancel">取 消</el-button>
    </div>
    <el-dialog :title="dialog.title" v-model="dialog.visible" width="750px" append-to-body>
      <div v-if="dialog.visible">
        <line-charts title="损失函数" :legend="legend" :series="series" :x-axis="xAxis" height="400px" />
        <div style="text-align: center;color: #707070;font-weight: bold;font-size: 16px;margin-top: -40px">
          {{props.healthState}}
        </div>
      </div>
      <div style="font-size: 18px;font-weight: bold;color: rgb(70, 70, 70)">四种指标</div>
      <div class="table">
        <el-table :data="enhanceTrainingList" class="column">
          <el-table-column label="MMD" align="center">
            <template #default="scope">
              {{formatNumber(scope.row.mmd)}}
            </template>
          </el-table-column>
          <el-table-column label="KLD" align="center">
            <template #default="scope">
              {{formatNumber(scope.row.kld)}}
            </template>
          </el-table-column>
          <el-table-column label="ED" align="center">
            <template #default="scope">
              {{formatNumber(scope.row.ed)}}
            </template>
          </el-table-column>
          <el-table-column label="CS" align="center">
            <template #default="scope">
              {{formatNumber(scope.row.cs)}}
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div class="button-group">
        <el-button type="warning" @click="reTrain">重新训练</el-button>
        <el-button type="success" @click="saveData">保存模型及参数</el-button>
        <el-button type="primary" @click="exportData">保存结果</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script setup name="Augmentation" lang="ts">
import { listAugmentation, delAugmentation, addAugmentation, updateAugmentation } from '@/api/wyl/dataStrengthen';
import { AugmentationVO, AugmentationQuery, AugmentationForm } from '@/api/wyl/dataStrengthen/types';
import { propTypes } from "@/utils/propTypes";
import axios from "_axios@1.6.2@axios";
import { globalHeaders } from "@/utils/request";
import { blobValidate } from "@/utils/ruoyi";
import * as XLSX from "_xlsx@0.18.5@xlsx";
import FileSaver from "file-saver";
import { getEnhanceTraining } from "@/api/wyl/strengthTrain";
import { EnhanceTrainingForm, EnhanceTrainingVO } from "@/api/wyl/strengthTrain/types";
const props = defineProps({
  detailId: propTypes.string.def(""),
  ossId: propTypes.string.def(""),
  healthState: propTypes.string.def("")
})
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const enhanceTrainingList = ref<EnhanceTrainingVO[]>([]);
const augmentationList = ref<AugmentationVO[]>([]);
const buttonLoading = ref(false);
const loading = ref(true);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const showSearch = ref(true);
const ids = ref<Array<string | number>>([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const showTable = ref(false)
const legend = ref([] as any[])
const series = ref([] as any[])
const xAxis = ref([] as any[])
const baseURL = import.meta.env.VITE_APP_BASE_API;

const queryFormRef = ref<ElFormInstance>();
const augmentationFormRef = ref<ElFormInstance>();

const dialog = reactive<DialogOption>({
  visible: false,
  title: ''
});

const initFormData: AugmentationForm = {
  id: undefined,
  detailId: undefined,
  batchSize: undefined,
  iterationNum: undefined,
  generatorRate: undefined,
  discriminatorRate: undefined,
  sampleNum: undefined,
}
const enhanceFormData: EnhanceTrainingForm = {
  id: undefined,
  detailId: undefined,
  MMD: undefined,
  KLD: undefined,
  ED: undefined,
  CS: undefined,
}
const data = reactive<PageData<AugmentationForm, AugmentationQuery>>({
  form: {...initFormData},
  queryParams: {
    pageNum: 1,
    pageSize: 10,
    detailId: undefined,
    batchSize: undefined,
    iterationNum: undefined,
    generatorRate: undefined,
    discriminatorRate: undefined,
    sampleNum: undefined,
    params: {
    }
  },
  rules: {
    detailId: [
      { required: true, message: "数据集详情Id不能为空", trigger: "blur" }
    ],
    batchSize: [
      { required: true, message: "批量大小不能为空", trigger: "blur" }
    ],
    iterationNum: [
      { required: true, message: "迭代次数不能为空", trigger: "blur" }
    ],
    generatorRate: [
      { required: true, message: "生成器学习率不能为空", trigger: "blur" }
    ],
    discriminatorRate: [
      { required: true, message: "判别器学习率不能为空", trigger: "blur" }
    ],
    sampleNum: [
      { required: true, message: "生成样本个数不能为空", trigger: "blur" }
    ],
  }
});
const handleExport = () => {
  proxy?.download('system/enhanceTraining/export', {
    ...queryParams.value
  }, `enhanceTraining_${new Date().getTime()}.xlsx`)
}
const { queryParams, form, rules } = toRefs(data);
const exportData = async () => {
  const url = baseURL + '/resource/oss/download/' + props.ossId;
  const res = await axios({
    method: 'get',
    url: url,
    responseType: 'blob',
    headers: globalHeaders()
  });
  const blob = new Blob([res.data], { type: 'application/octet-stream' });
  console.log('blob', blob)
  FileSaver.saveAs(blob, decodeURIComponent(res.headers['download-filename'] as string));
}
const reTrain = () => {
  dialog.visible = false;
}
const startTrain = async () => {
  console.log("ossId", props.ossId);
  await getData(props.ossId)
}
/** 查询【请填写功能名称】列表 */
const getList = async () => {
  loading.value = true;
  const res = await listAugmentation(queryParams.value);
  augmentationList.value = res.rows;
  total.value = res.total;
  loading.value = false;
}

/** 取消按钮 */
const cancel = () => {
  reset();
  dialog.visible = false;
}

/** 表单重置 */
const reset = () => {
  form.value = {...initFormData};
  augmentationFormRef.value?.resetFields();
}
const formatNumber = (value: string) => {
  // Convert to number, divide by 1000, and format with 3 decimal places
  return (Number(value) / 1000).toFixed(3);
};
/** 搜索按钮操作 */
const handleQuery = () => {
  queryParams.value.pageNum = 1;
  getList();
}

/** 重置按钮操作 */
const resetQuery = () => {
  queryFormRef.value?.resetFields();
  handleQuery();
}

/** 多选框选中数据 */
const handleSelectionChange = (selection: AugmentationVO[]) => {
  ids.value = selection.map(item => item.id);
  single.value = selection.length != 1;
  multiple.value = !selection.length;
}

/** 提交按钮 */
const submitForm = async () => {
  form.value.detailId = props.detailId
  augmentationFormRef.value?.validate(async (valid: boolean) => {
    if (valid) {
      buttonLoading.value = true;
      await getList();
      await startTrain();
      const res = await getEnhanceTraining(props.detailId)
      enhanceTrainingList.value = [];
      enhanceTrainingList.value.push(res.data)
      console.log("list", enhanceTrainingList);
      dialog.visible = true;
    }
  });
}
const saveData = async () => {
  if (form.value.id) {
    await updateAugmentation(form.value).finally(() => buttonLoading.value = false);
  } else {
    await addAugmentation(form.value).finally(() => buttonLoading.value = false);
  }
  proxy?.$modal.msgSuccess("保存成功");
}
/** 删除按钮操作 */
const handleDelete = async (row?: AugmentationVO) => {
  const _ids = row?.id || ids.value;
  await proxy?.$modal.confirm('是否确认删除【请填写功能名称】编号为"' + _ids + '"的数据项？').finally(() => loading.value = false);
  await delAugmentation(_ids);
  proxy?.$modal.msgSuccess("删除成功");
  await getList();
}

onMounted(() => {
  getList();
});
const getData = async (ossId: string) => {
  const url = baseURL + '/resource/oss/download/' + ossId;
  const res = await axios({
    method: 'get',
    url: url,
    responseType: 'blob',
    headers: globalHeaders()
  });
  const isBlob = blobValidate(res.data);
  if (isBlob) {
    const blob = new Blob([res.data], { type: 'application/octet-stream' });
    console.log('blob', blob)
    await readExcel(blob)
  }
}

const readExcel = async (file: Blob) => {
  // 确保有文件可读
  if (!file) {
    alert('请先选择一个Excel文件');
    return;
  }
  series.value = [];
  const reader = new FileReader();
  // 读取文件完成后的回调
  reader.onload = (event) => {
    const data = new Uint8Array((event.target as any).result);
    // 使用 xlsx 读取数据
    const workbook = XLSX.read(data, { type: 'array' });
    console.log("data", workbook)
    // 获取第一个工作表
    const firstSheetName = workbook.SheetNames[0];
    const worksheet = workbook.Sheets[firstSheetName];
    const jsonData = ref([] as any[])
    console.log("reader", jsonData.value)
    // 将 Excel 数据转换为 JSON 对象
    jsonData.value = XLSX.utils.sheet_to_json(worksheet, { header: 1 });
    if (jsonData.value.length > 0) {
      jsonData.value[0].forEach((item: any) => {
        legend.value.push(item);
      });
    }
    xAxis.value = Array.from({ length: jsonData.value.length - 1 }, (_, i) => String(i + 1));
    for (let j = 0; j < jsonData.value[0].length; j++) {
      const colData = jsonData.value.slice(1).filter((row: string | any[]) => row.length >= 2).map((row: any[]) => row[j]);
      // 创建一个新的数据对象
      const newData = {
        name: legend.value[j],  // 使用 legend 中的数据作为 name 属性
        type: 'line',             // 设置 type 属性为 'line'
        smooth: true,
        data: colData             // 将列数据推导到 data 属性里
      };
      // 将数据对象添加到 dataDict 数组
      series.value.push(newData);
    }
    showTable.value = true;
    console.log("legend:", legend.value);
    console.log("series:", series.value);
  };
  // 读取文件为 ArrayBuffer
  reader.readAsArrayBuffer(file);
};
</script>

<style>
.dialog-footer{
  text-align: center;
}
.button-group{
  margin-top: 20px;
  text-align: center;
}
.column{
  margin-left: 20px;
  width: 650px;
}
.table {
  margin-top: 10px;
}
</style>
